//
//  JS2OCvc.m
//  testAAA
//
//  Created by tianNanYiHao on 2019/11/1.
//  Copyright © 2019 tianNanYiHao. All rights reserved.
//

#import "JS2OCvc.h"
#import <WebKit/WebKit.h>
#import <JavaScriptCore/JavaScriptCore.h>

// js方法绑定自定义事件, 实现js调用原生方法后,获取回调
//https://blog.csdn.net/hanhailong18/article/details/69102820
//https://blog.csdn.net/hanhailong18/article/details/69102820
//https://blog.csdn.net/hanhailong18/article/details/69102820
//https://blog.csdn.net/hanhailong18/article/details/69102820
//https://blog.csdn.net/hanhailong18/article/details/69102820
//https://blog.csdn.net/hanhailong18/article/details/69102820
//https://blog.csdn.net/hanhailong18/article/details/69102820
//https://blog.csdn.net/hanhailong18/article/details/69102820

@interface JS2OCvc ()<WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler>
@property (nonatomic, strong) WKWebView *webview;
@property (nonatomic, strong) UIButton* btn1;
@property (nonatomic, assign) CGFloat halfHeight;
@property (nonatomic, strong ) UILabel *lab;
@end

@implementation JS2OCvc


-(UILabel*)lab{
    if (!_lab) {
        _lab = [[UILabel alloc] initWithFrame:CGRectMake(10, self.halfHeight+80, 280, 50)];
        _lab.text = @"等待js返回消息...";
        [_lab setBackgroundColor:[UIColor greenColor]];
    }
    return  _lab;
}

- (UIButton*)btn1{
    if (!_btn1) {
        _btn1 = [[UIButton alloc] init];
        [_btn1 setTitle:@"oc按钮:点我将xwft对象注入js" forState:UIControlStateNormal];
        _btn1.frame = CGRectMake(20, self.halfHeight, 280, 50);
        [_btn1 setBackgroundColor:[UIColor greenColor]];
        [_btn1 addTarget:self action:@selector(addxwftTojs) forControlEvents:UIControlEventTouchUpInside];
    }
    return  _btn1;
}

-(WKWebView*)webview{
    if (!_webview) {
        // https://www.jianshu.com/p/5cf0d241ae12 wkwebview参考贴
        
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
        //这个类主要用来做native与JavaScript的交互管理
        WKUserContentController * wkUController = [[WKUserContentController alloc] init];
        config.userContentController = wkUController;
        
        
        _webview = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height/2) configuration:config];
        _webview.UIDelegate = self;
        _webview.navigationDelegate = self;
        
        NSString *path = [[NSBundle mainBundle] pathForResource:@"Test2" ofType:@"html"];
        NSString *htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        NSString *basePath = [[NSBundle mainBundle] bundlePath];
        NSURL *baseURL = [NSURL fileURLWithPath:basePath];
        [_webview loadHTMLString:htmlString baseURL:baseURL];
        
    }
    return _webview;
}

// oc 向 js 注入 xwft 对象
- (void)addxwftTojs{
    // WKWebView 方式 进行js注入 xwft
    NSString *jscode = @"var xwft = {}";
    [self.webview evaluateJavaScript:jscode completionHandler:^(id _Nullable data, NSError * _Nullable error) {
        
    }];

    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor grayColor];
    
    self.halfHeight = [UIScreen mainScreen].bounds.size.height/2;
    
    [self.view addSubview:self.webview];
    [self.view addSubview:self.btn1];
    [self.view addSubview:self.lab];

    // oc 注册 js函数的监听, 通过代理方式执行响应
    [self.webview.configuration.userContentController addScriptMessageHandler:self name:@"changeOCtitle"];
}


//注意：遵守WKScriptMessageHandler协议，代理是由WKUserContentControl设置
//通过接收JS传出消息的name进行捕捉的回调方法  js调OC
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    NSLog(@"%@",[message body]); // js方法的参数体 并且js函数的入参必须对象, 不能多参数,否则只能获取最后一个参数
    NSLog(@"%@",[message frameInfo]); //
    NSLog(@"%@",[message name]); //监听的方法名
    
    self.lab.text = message.body[@"param"];
    
    NSString *jsString = [NSString stringWithFormat:@"ocCallJS('%@')",self.lab.text];
    [self.webview evaluateJavaScript:jsString completionHandler:^(id _Nullable data, NSError * _Nullable error) {
        
    }];
    
}


//===================================== navigationDelegate =====================================
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    
    
}
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
    
}
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
    
}
// 页面加载完成之后调用
// oc想要调用js 方法, 必须放到页面加载完成后
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    

    
}
//提交发生错误时调用
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    
}
// 接收到服务器跳转请求即服务重定向时之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
}
// 根据WebView对于即将跳转的HTTP请求头信息和相关信息来决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    
    
    decisionHandler(WKNavigationActionPolicyAllow);
}

// 根据客户端受到的服务器响应头以及response相关信息来决定是否可以跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    NSString * urlStr = navigationResponse.response.URL.absoluteString;
    NSLog(@"当前跳转地址：%@",urlStr);
    //允许跳转
    decisionHandler(WKNavigationResponsePolicyAllow);
    //不允许跳转
    //decisionHandler(WKNavigationResponsePolicyCancel);
}
//进程被终止时调用
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{
}












//===================================== UIDelegate =====================================
/**
 *  web界面中有弹出警告框时调用 --- js的弹框,弹框输入等, 均由wkwebview 接管并实现, 若不实现无弹框
 *
 *  @param webView           实现该代理的webview
 *  @param message           警告框中的内容
 *  @param completionHandler 警告框消失调用
 */
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"HTML的弹出框" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
// 确认框
//JavaScript调用confirm方法后回调的方法 confirm是js中的确定框，需要在block中把用户选择的情况传递进去
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
// 输入框
//JavaScript调用prompt方法后回调的方法 prompt是js中的输入框 需要在block中把用户输入的信息传入
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.text = defaultText;
    }];
    [alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields[0].text?:@"");
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
// 页面是弹出窗口 _blank 处理
//- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
////    if (!navigationAction.targetFrame.isMainFrame) {
////        [webView loadRequest:navigationAction.request];
////    }
//    return nil;
//}

@end
